Enter the directory of the maca folder on your drive and the name of the tissue you want to analyze.

tissue_of_interest = "Bladder"

Load the requisite packages and some additional helper functions.

library(here)
here() starts at /Users/olgabot/code/tabula-muris
library(useful)
Loading required package: ggplot2
library(Seurat)
Loading required package: cowplot

Attaching package: 'cowplot'
The following object is masked from 'package:ggplot2':

    ggsave
Loading required package: Matrix
Warning: namespace 'Biobase' is not available and has been replaced
by .GlobalEnv when processing object 'call.'
Warning: namespace 'lme4' is not available and has been replaced
by .GlobalEnv when processing object 'call.'
Warning: namespace 'MatrixModels' is not available and has been replaced
by .GlobalEnv when processing object 'call.'
Warning: namespace 'Biobase' is not available and has been replaced
by .GlobalEnv when processing object 'call.'
Warning: namespace 'lme4' is not available and has been replaced
by .GlobalEnv when processing object 'call.'
Warning: namespace 'MatrixModels' is not available and has been replaced
by .GlobalEnv when processing object 'call.'
library(dplyr)
Warning: package 'dplyr' was built under R version 3.4.2

Attaching package: 'dplyr'
The following objects are masked from 'package:stats':

    filter, lag
The following objects are masked from 'package:base':

    intersect, setdiff, setequal, union
library(Matrix)

save_dir = here('00_data_ingest', 'tissue_robj')
droplet_data_dir = here('00_data_ingest', '01_droplet_raw_data')
# read the metadata to get the plates we want
droplet_metadata_filename = here('00_data_ingest', '01_droplet_raw_data', 'metadata_droplet.csv')

droplet_metadata <- read.csv(droplet_metadata_filename, sep=",", header = TRUE)
colnames(droplet_metadata)[1] <- "channel"
droplet_metadata

Subset the metadata on the tissue.

tissue_metadata = filter(droplet_metadata, tissue == tissue_of_interest)[,c('channel','tissue','subtissue','mouse.sex', 'mouse.id')]
tissue_metadata

Use only the metadata rows corresponding to Bladder plates. Make a plate barcode dataframe to “expand” the per-plate metadata to be per-cell.

# Load the gene names and set the metadata columns by opening the first file

subfolder = paste0(tissue_of_interest, '-', tissue_metadata$channel[1])
raw.data <- Read10X(data.dir = here('00_data_ingest', '01_droplet_raw_data', 'droplet', subfolder))
colnames(raw.data) <- lapply(colnames(raw.data), function(x) paste0(tissue_metadata$channel[1], '_', x))
meta.data = data.frame(row.names = colnames(raw.data))
meta.data['channel'] = tissue_metadata$channel[1]

if (length(tissue_metadata$channel) > 1){
  # Some tissues, like Thymus and Heart had only one channel
  for(i in 2:nrow(tissue_metadata)){
    subfolder = paste0(tissue_of_interest, '-', tissue_metadata$channel[i])
    new.data <- Read10X(data.dir = here('00_data_ingest', '01_droplet_raw_data', 'droplet', subfolder))
    colnames(new.data) <- lapply(colnames(new.data), function(x) paste0(tissue_metadata$channel[i], '_', x))
    
    new.metadata = data.frame(row.names = colnames(new.data))
    new.metadata['channel'] = tissue_metadata$channel[i]
    
    raw.data = cbind(raw.data, new.data)
    meta.data = rbind(meta.data, new.metadata)
  }
}

rnames = row.names(meta.data)
meta.data <- merge(meta.data, tissue_metadata, sort = F)
row.names(meta.data) <- rnames
dim(raw.data)
[1] 23433  2500
corner(raw.data)
[1] 0 0 0 1 0
head(meta.data)

Process the raw data and load it into the Seurat object.

# Find ERCC's, compute the percent ERCC, and drop them from the raw data.
erccs <- grep(pattern = "^ERCC-", x = rownames(x = raw.data), value = TRUE)
percent.ercc <- Matrix::colSums(raw.data[erccs, ])/Matrix::colSums(raw.data)
ercc.index <- grep(pattern = "^ERCC-", x = rownames(x = raw.data), value = FALSE)
raw.data <- raw.data[-ercc.index,]

# Create the Seurat object with all the data
tiss <- CreateSeuratObject(raw.data = raw.data, project = tissue_of_interest, 
                    min.cells = 5, min.genes = 5)

tiss <- AddMetaData(object = tiss, meta.data)
tiss <- AddMetaData(object = tiss, percent.ercc, col.name = "percent.ercc")

# Create metadata columns for annotations and subannotations
tiss@meta.data[,'annotation'] <- NA
tiss@meta.data[,'subannotation'] <- NA

Calculate percent ribosomal genes.

ribo.genes <- grep(pattern = "^Rp[sl][[:digit:]]", x = rownames(x = tiss@data), value = TRUE)
percent.ribo <- Matrix::colSums(tiss@raw.data[ribo.genes, ])/Matrix::colSums(tiss@raw.data)
tiss <- AddMetaData(object = tiss, metadata = percent.ribo, col.name = "percent.ribo")

A sanity check: genes per cell vs reads per cell.

GenePlot(object = tiss, gene1 = "nUMI", gene2 = "nGene", use.raw=T)

Filter out cells with few reads and few genes.

tiss <- FilterCells(object = tiss, subset.names = c("nGene", "nUMI"), 
    low.thresholds = c(500, 1000), high.thresholds = c(25000, 5000000))

Normalize the data, then regress out correlation with total reads

tiss <- NormalizeData(object = tiss)
tiss <- ScaleData(object = tiss, vars.to.regress = c("nUMI", "percent.ribo","Rn45s"))
[1] "Regressing out nUMI"         "Regressing out percent.ribo"
[3] "Regressing out Rn45s"       

  |                                                                       
  |                                                                 |   0%
  |                                                                       
  |                                                                 |   1%
  |                                                                       
  |=                                                                |   1%
  |                                                                       
  |=                                                                |   2%
  |                                                                       
  |==                                                               |   3%
  |                                                                       
  |===                                                              |   4%
  |                                                                       
  |===                                                              |   5%
  |                                                                       
  |====                                                             |   5%
  |                                                                       
  |====                                                             |   6%
  |                                                                       
  |====                                                             |   7%
  |                                                                       
  |=====                                                            |   7%
  |                                                                       
  |=====                                                            |   8%
  |                                                                       
  |======                                                           |   9%
  |                                                                       
  |=======                                                          |  10%
  |                                                                       
  |=======                                                          |  11%
  |                                                                       
  |========                                                         |  12%
  |                                                                       
  |========                                                         |  13%
  |                                                                       
  |=========                                                        |  14%
  |                                                                       
  |==========                                                       |  15%
  |                                                                       
  |==========                                                       |  16%
  |                                                                       
  |===========                                                      |  16%
  |                                                                       
  |===========                                                      |  17%
  |                                                                       
  |===========                                                      |  18%
  |                                                                       
  |============                                                     |  18%
  |                                                                       
  |============                                                     |  19%
  |                                                                       
  |=============                                                    |  20%
  |                                                                       
  |==============                                                   |  21%
  |                                                                       
  |==============                                                   |  22%
  |                                                                       
  |===============                                                  |  23%
  |                                                                       
  |===============                                                  |  24%
  |                                                                       
  |================                                                 |  24%
  |                                                                       
  |================                                                 |  25%
  |                                                                       
  |=================                                                |  26%
  |                                                                       
  |==================                                               |  27%
  |                                                                       
  |==================                                               |  28%
  |                                                                       
  |===================                                              |  29%
  |                                                                       
  |===================                                              |  30%
  |                                                                       
  |====================                                             |  30%
  |                                                                       
  |====================                                             |  31%
  |                                                                       
  |=====================                                            |  32%
  |                                                                       
  |======================                                           |  33%
  |                                                                       
  |======================                                           |  34%
  |                                                                       
  |=======================                                          |  35%
  |                                                                       
  |=======================                                          |  36%
  |                                                                       
  |========================                                         |  36%
  |                                                                       
  |========================                                         |  37%
  |                                                                       
  |=========================                                        |  38%
  |                                                                       
  |=========================                                        |  39%
  |                                                                       
  |==========================                                       |  40%
  |                                                                       
  |==========================                                       |  41%
  |                                                                       
  |===========================                                      |  41%
  |                                                                       
  |===========================                                      |  42%
  |                                                                       
  |============================                                     |  43%
  |                                                                       
  |=============================                                    |  44%
  |                                                                       
  |=============================                                    |  45%
  |                                                                       
  |==============================                                   |  46%
  |                                                                       
  |==============================                                   |  47%
  |                                                                       
  |===============================                                  |  47%
  |                                                                       
  |===============================                                  |  48%
  |                                                                       
  |================================                                 |  49%
  |                                                                       
  |================================                                 |  50%
  |                                                                       
  |=================================                                |  51%
  |                                                                       
  |==================================                               |  52%
  |                                                                       
  |==================================                               |  53%
  |                                                                       
  |===================================                              |  53%
  |                                                                       
  |===================================                              |  54%
  |                                                                       
  |====================================                             |  55%
  |                                                                       
  |====================================                             |  56%
  |                                                                       
  |=====================================                            |  57%
  |                                                                       
  |======================================                           |  58%
  |                                                                       
  |======================================                           |  59%
  |                                                                       
  |=======================================                          |  59%
  |                                                                       
  |=======================================                          |  60%
  |                                                                       
  |========================================                         |  61%
  |                                                                       
  |========================================                         |  62%
  |                                                                       
  |=========================================                        |  63%
  |                                                                       
  |=========================================                        |  64%
  |                                                                       
  |==========================================                       |  64%
  |                                                                       
  |==========================================                       |  65%
  |                                                                       
  |===========================================                      |  66%
  |                                                                       
  |===========================================                      |  67%
  |                                                                       
  |============================================                     |  68%
  |                                                                       
  |=============================================                    |  69%
  |                                                                       
  |=============================================                    |  70%
  |                                                                       
  |==============================================                   |  70%
  |                                                                       
  |==============================================                   |  71%
  |                                                                       
  |===============================================                  |  72%
  |                                                                       
  |===============================================                  |  73%
  |                                                                       
  |================================================                 |  74%
  |                                                                       
  |=================================================                |  75%
  |                                                                       
  |=================================================                |  76%
  |                                                                       
  |==================================================               |  76%
  |                                                                       
  |==================================================               |  77%
  |                                                                       
  |===================================================              |  78%
  |                                                                       
  |===================================================              |  79%
  |                                                                       
  |====================================================             |  80%
  |                                                                       
  |=====================================================            |  81%
  |                                                                       
  |=====================================================            |  82%
  |                                                                       
  |======================================================           |  82%
  |                                                                       
  |======================================================           |  83%
  |                                                                       
  |======================================================           |  84%
  |                                                                       
  |=======================================================          |  84%
  |                                                                       
  |=======================================================          |  85%
  |                                                                       
  |========================================================         |  86%
  |                                                                       
  |=========================================================        |  87%
  |                                                                       
  |=========================================================        |  88%
  |                                                                       
  |==========================================================       |  89%
  |                                                                       
  |==========================================================       |  90%
  |                                                                       
  |===========================================================      |  91%
  |                                                                       
  |============================================================     |  92%
  |                                                                       
  |============================================================     |  93%
  |                                                                       
  |=============================================================    |  93%
  |                                                                       
  |=============================================================    |  94%
  |                                                                       
  |=============================================================    |  95%
  |                                                                       
  |==============================================================   |  95%
  |                                                                       
  |==============================================================   |  96%
  |                                                                       
  |===============================================================  |  97%
  |                                                                       
  |================================================================ |  98%
  |                                                                       
  |================================================================ |  99%
  |                                                                       
  |=================================================================|  99%
  |                                                                       
  |=================================================================| 100%
[1] "Scaling data matrix"

  |                                                                       
  |                                                                 |   0%
  |                                                                       
  |=================================================================| 100%
tiss <- FindVariableGenes(object = tiss, do.plot = TRUE, x.high.cutoff = Inf, y.cutoff = 0.5)

Run Principal Component Analysis.

tiss <- RunPCA(object = tiss, do.print = FALSE)
tiss <- ProjectPCA(object = tiss, do.print = FALSE)

Later on (in FindClusters and TSNE) you will pick a number of principal components to use. This has the effect of keeping the major directions of variation in the data and, ideally, supressing noise. There is no correct answer to the number to use, but a decent rule of thumb is to go until the plot plateaus.

PCElbowPlot(object = tiss)

Choose the number of principal components to use.

# Set number of principal components. 
n.pcs = 15

The clustering is performed based on a nearest neighbors graph. Cells that have similar expression will be joined together. The Louvain algorithm looks for groups of cells with high modularity–more connections within the group than between groups. The resolution parameter determines the scale…higher resolution will give more clusters, lower resolution will give fewer.

For the top-level clustering, aim to under-cluster instead of over-cluster. It will be easy to subset groups and further analyze them below.

# Set resolution 
res.used <- 1.0

tiss <- FindClusters(object = tiss, reduction.type = "pca", dims.use = 1:n.pcs, 
    resolution = res.used, print.output = 0, save.SNN = TRUE)

To visualize

# If cells are too spread out, you can raise the perplexity. If you have few cells, try a lower perplexity (but never less than 10).
tiss <- RunTSNE(object = tiss, dims.use = 1:n.pcs, seed.use = 10, perplexity=30, dim.embed = 2)
# note that you can set do.label=T to help label individual clusters
TSNEPlot(object = tiss, do.label = T)

Check expression of genes of interset.

VlnPlot(tiss, genes_to_check)

Dotplots let you see the intensity of exppression and the fraction of cells expressing for each of your genes of interest.

How big are the clusters?

table(tiss@ident)

  0   1   2   3   4   5   6   7   8   9 
501 391 329 313 266 219 187 169  68  57 

Which markers identify a specific cluster?

clust.markers <- FindMarkers(object = tiss, ident.1 = 2, ident.2 = 1, only.pos = TRUE, min.pct = 0.25, thresh.use = 0.25)
print(x = head(x= clust.markers, n = 10))
               p_val avg_diff pct.1 pct.2
Dcn    1.905333e-316 3.298991 0.997 0.665
Plac9  1.298320e-298 3.112769 0.997 0.292
Col1a2 1.345735e-288 2.941688 1.000 0.708
Tmsb10 3.680076e-286 2.093490 1.000 0.964
Nbl1   8.008946e-268 2.908757 0.994 0.399
Col1a1 1.885544e-264 2.622059 1.000 0.614
Gsn    1.771160e-263 2.519395 1.000 0.992
Lgals1 4.033902e-259 2.831648 1.000 0.299
Col3a1 6.349244e-259 2.937657 0.997 0.455
Sparc  1.132132e-258 2.621723 1.000 0.716

You can also compute all markers for all clusters at once. This may take some time.

tiss.markers <- FindAllMarkers(object = tiss, only.pos = TRUE, min.pct = 0.25, thresh.use = 0.25)

Display the top markers you computed above.

tiss.markers %>% group_by(cluster) %>% top_n(25, avg_diff)

tiss= BuildClusterTree(tiss)
[1] "Finished averaging RNA for cluster 0"
[1] "Finished averaging RNA for cluster 1"
[1] "Finished averaging RNA for cluster 2"
[1] "Finished averaging RNA for cluster 3"
[1] "Finished averaging RNA for cluster 4"
[1] "Finished averaging RNA for cluster 5"
[1] "Finished averaging RNA for cluster 6"
[1] "Finished averaging RNA for cluster 7"
[1] "Finished averaging RNA for cluster 8"
[1] "Finished averaging RNA for cluster 9"

Node18_markers = FindAllMarkersNode(tiss, node = 18)
Node18_markers %>% group_by(cluster) %>% top_n(15, avg_diff)

Assigning cell type identity to clusters

At a coarse level, we can use canonical markers to match the unbiased clustering to known cell types:

# stash current cluster IDs
tiss <- StashIdent(object = tiss, save.name = "cluster.ids")

# enumerate current cluster IDs and the labels for them
cluster.ids <- c(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
annotation <- c("mesenchymal cell", "bladder cell" , "mesenchymal cell", "bladder cell", "basal cell of urothelium", "bladder cell", "mesenchymal cell", "mesenchymal cell", "endothelial cell", "leukocyte")
cell_ontology_id <- c("CL:0008019", "CL:1001319" , "CL:0008019", "CL:1001319", "CL:1000486", "CL:1001319", "CL:0008019", "CL:0008019", "CL:0000115", "CL:0000738")

tiss@meta.data[,'annotation'] <- plyr::mapvalues(x = tiss@ident, from = cluster.ids, to = annotation)
tiss@meta.data[,'cell_ontology_id'] <- plyr::mapvalues(x = tiss@ident, from = cluster.ids, to = cell_ontology_id)

tiss@meta.data[tiss@cell.names,'annotation'] <- as.character(tiss@meta.data$annotation)
tiss@meta.data[tiss@cell.names,'cell_ontology_id'] <- as.character(tiss@meta.data$cell_ontology_id)

TSNEPlot(object = tiss, do.label = TRUE, pt.size = 0.5, group.by='annotation')

Checking for batch effects

Color by metadata, like plate barcode, to check for batch effects.

TSNEPlot(object = tiss, do.return = TRUE, group.by = "channel")

TSNEPlot(object = tiss, do.return = TRUE, group.by = "mouse.sex")

Print a table showing the count of cells in each identity category from each plate.

table(as.character(tiss@ident), as.character(tiss@meta.data$channel))
   
    10X_P4_3 10X_P4_4 10X_P7_7
  0       30      454       17
  1       20      212      159
  2       40      278       11
  3       28      248       37
  4       10      204       52
  5        6      198       15
  6        9      116       62
  7        0        2      167
  8        3       45       20
  9        3       26       28
table(as.character(tiss@ident), as.character(tiss@meta.data$mouse.id))
   
    3-F-56 3-M-8 3-M-9
  0     17    30   454
  1    159    20   212
  2     11    40   278
  3     37    28   248
  4     52    10   204
  5     15     6   198
  6     62     9   116
  7    167     0     2
  8     20     3    45
  9     28     3    26

Subset and iterate

We can repeat the above analysis on a subset of cells, defined using cluster IDs or some other metadata. This is a good way to drill down and find substructure.

First subset

# Subset data based on cluster id
subtiss <- SubsetData(object = tiss, ident.use = c(3), do.center = F, do.scale = F, cells.use = )

# To subset data based on annotation or other metadata, you can explicitly pass cell names

cells.to.use = tiss@cell.names[which(tiss@meta.data$mouse.sex == 'F')]
subtiss <- SubsetData(object = tiss, cells.use = cells.to.use, do.center = F, do.scale = F)
subtiss <- NormalizeData(object = subtiss)
subtiss <- ScaleData(object = subtiss, vars.to.regress = c("nUMI", "percent.ribo","Rn45s"))
[1] "Regressing out nUMI"         "Regressing out percent.ribo"
[3] "Regressing out Rn45s"       

  |                                                                       
  |                                                                 |   0%
  |                                                                       
  |                                                                 |   1%
  |                                                                       
  |=                                                                |   1%
  |                                                                       
  |=                                                                |   2%
  |                                                                       
  |==                                                               |   3%
  |                                                                       
  |===                                                              |   4%
  |                                                                       
  |===                                                              |   5%
  |                                                                       
  |====                                                             |   5%
  |                                                                       
  |====                                                             |   6%
  |                                                                       
  |====                                                             |   7%
  |                                                                       
  |=====                                                            |   7%
  |                                                                       
  |=====                                                            |   8%
  |                                                                       
  |======                                                           |   9%
  |                                                                       
  |=======                                                          |  10%
  |                                                                       
  |=======                                                          |  11%
  |                                                                       
  |========                                                         |  12%
  |                                                                       
  |========                                                         |  13%
  |                                                                       
  |=========                                                        |  14%
  |                                                                       
  |==========                                                       |  15%
  |                                                                       
  |==========                                                       |  16%
  |                                                                       
  |===========                                                      |  16%
  |                                                                       
  |===========                                                      |  17%
  |                                                                       
  |===========                                                      |  18%
  |                                                                       
  |============                                                     |  18%
  |                                                                       
  |============                                                     |  19%
  |                                                                       
  |=============                                                    |  20%
  |                                                                       
  |==============                                                   |  21%
  |                                                                       
  |==============                                                   |  22%
  |                                                                       
  |===============                                                  |  23%
  |                                                                       
  |===============                                                  |  24%
  |                                                                       
  |================                                                 |  24%
  |                                                                       
  |================                                                 |  25%
  |                                                                       
  |=================                                                |  26%
  |                                                                       
  |==================                                               |  27%
  |                                                                       
  |==================                                               |  28%
  |                                                                       
  |===================                                              |  29%
  |                                                                       
  |===================                                              |  30%
  |                                                                       
  |====================                                             |  30%
  |                                                                       
  |====================                                             |  31%
  |                                                                       
  |=====================                                            |  32%
  |                                                                       
  |======================                                           |  33%
  |                                                                       
  |======================                                           |  34%
  |                                                                       
  |=======================                                          |  35%
  |                                                                       
  |=======================                                          |  36%
  |                                                                       
  |========================                                         |  36%
  |                                                                       
  |========================                                         |  37%
  |                                                                       
  |=========================                                        |  38%
  |                                                                       
  |=========================                                        |  39%
  |                                                                       
  |==========================                                       |  40%
  |                                                                       
  |==========================                                       |  41%
  |                                                                       
  |===========================                                      |  41%
  |                                                                       
  |===========================                                      |  42%
  |                                                                       
  |============================                                     |  43%
  |                                                                       
  |=============================                                    |  44%
  |                                                                       
  |=============================                                    |  45%
  |                                                                       
  |==============================                                   |  46%
  |                                                                       
  |==============================                                   |  47%
  |                                                                       
  |===============================                                  |  47%
  |                                                                       
  |===============================                                  |  48%
  |                                                                       
  |================================                                 |  49%
  |                                                                       
  |================================                                 |  50%
  |                                                                       
  |=================================                                |  51%
  |                                                                       
  |==================================                               |  52%
  |                                                                       
  |==================================                               |  53%
  |                                                                       
  |===================================                              |  53%
  |                                                                       
  |===================================                              |  54%
  |                                                                       
  |====================================                             |  55%
  |                                                                       
  |====================================                             |  56%
  |                                                                       
  |=====================================                            |  57%
  |                                                                       
  |======================================                           |  58%
  |                                                                       
  |======================================                           |  59%
  |                                                                       
  |=======================================                          |  59%
  |                                                                       
  |=======================================                          |  60%
  |                                                                       
  |========================================                         |  61%
  |                                                                       
  |========================================                         |  62%
  |                                                                       
  |=========================================                        |  63%
  |                                                                       
  |=========================================                        |  64%
  |                                                                       
  |==========================================                       |  64%
  |                                                                       
  |==========================================                       |  65%
  |                                                                       
  |===========================================                      |  66%
  |                                                                       
  |===========================================                      |  67%
  |                                                                       
  |============================================                     |  68%
  |                                                                       
  |=============================================                    |  69%
  |                                                                       
  |=============================================                    |  70%
  |                                                                       
  |==============================================                   |  70%
  |                                                                       
  |==============================================                   |  71%
  |                                                                       
  |===============================================                  |  72%
  |                                                                       
  |===============================================                  |  73%
  |                                                                       
  |================================================                 |  74%
  |                                                                       
  |=================================================                |  75%
  |                                                                       
  |=================================================                |  76%
  |                                                                       
  |==================================================               |  76%
  |                                                                       
  |==================================================               |  77%
  |                                                                       
  |===================================================              |  78%
  |                                                                       
  |===================================================              |  79%
  |                                                                       
  |====================================================             |  80%
  |                                                                       
  |=====================================================            |  81%
  |                                                                       
  |=====================================================            |  82%
  |                                                                       
  |======================================================           |  82%
  |                                                                       
  |======================================================           |  83%
  |                                                                       
  |======================================================           |  84%
  |                                                                       
  |=======================================================          |  84%
  |                                                                       
  |=======================================================          |  85%
  |                                                                       
  |========================================================         |  86%
  |                                                                       
  |=========================================================        |  87%
  |                                                                       
  |=========================================================        |  88%
  |                                                                       
  |==========================================================       |  89%
  |                                                                       
  |==========================================================       |  90%
  |                                                                       
  |===========================================================      |  91%
  |                                                                       
  |============================================================     |  92%
  |                                                                       
  |============================================================     |  93%
  |                                                                       
  |=============================================================    |  93%
  |                                                                       
  |=============================================================    |  94%
  |                                                                       
  |=============================================================    |  95%
  |                                                                       
  |==============================================================   |  95%
  |                                                                       
  |==============================================================   |  96%
  |                                                                       
  |===============================================================  |  97%
  |                                                                       
  |================================================================ |  98%
  |                                                                       
  |================================================================ |  99%
  |                                                                       
  |=================================================================|  99%
  |                                                                       
  |=================================================================| 100%
[1] "Scaling data matrix"

  |                                                                       
  |                                                                 |   0%
  |                                                                       
  |=================================================================| 100%

Run Principal Component Analysis.

subtiss <- FindVariableGenes(object = subtiss, do.plot = TRUE, x.high.cutoff = Inf, y.cutoff = 0.8)

subtiss <- RunPCA(object = subtiss, pcs.compute = 20, weight.by.var = F)
[1] "PC1"
 [1] "Mef2c"   "Ctss"    "Mrc1"    "Lyz1"    "Fcer1g"  "H2-Eb1"  "Tyrobp" 
 [8] "C1qb"    "Tmsb4x"  "C1qc"    "Lrrc33"  "H2-Aa"   "C1qa"    "Csf1r"  
[15] "Laptm5"  "Lyz2"    "Ms4a7"   "Sfpi1"   "Pcp4l1"  "Lyn"     "Pld4"   
[22] "Bcam"    "Ly86"    "Emr1"    "Cd74"    "Tinagl1" "Cd53"    "Pf4"    
[29] "C5ar1"   "Lcp1"   
[1] ""
 [1] "Col3a1"   "Col1a1"   "Col1a2"   "Dcn"      "Mgp"      "Serping1"
 [7] "Rcn3"     "Dkk3"     "Sparc"    "Fstl1"    "Mmp2"     "Rarres2" 
[13] "Aebp1"    "Cygb"     "Pcolce"   "Col5a2"   "Fbln5"    "Prelp"   
[19] "Wnt2"     "Plac8"    "Vcan"     "C1s"      "Fn1"      "Tcf21"   
[25] "Col6a3"   "Col6a2"   "Igfbp6"   "C1ra"     "Thbs2"    "Nupr1"   
[1] ""
[1] ""
[1] "PC2"
 [1] "Sparcl1"       "Tm4sf1"        "Pcp4l1"        "Esam"         
 [5] "Timp3"         "Epas1"         "Cav1"          "Prss23"       
 [9] "Sdpr"          "Pecam1"        "Emcn"          "Eltd1"        
[13] "Cdh5"          "Podxl"         "Ecscr"         "Egfl7"        
[17] "Gng11"         "Jam2"          "Slc9a3r2"      "Flt1"         
[21] "Sncg"          "Gpr116"        "Apold1"        "Mmrn2"        
[25] "Abcb1a"        "Sorbs2"        "Gimap6"        "C130074G19Rik"
[29] "Utrn"          "Prkcdbp"      
[1] ""
 [1] "H2-Aa"   "H2-Ab1"  "Cd83"    "Tyrobp"  "Ctss"    "Lyz2"    "Lyz1"   
 [8] "H2-Eb1"  "Fcer1g"  "Sfpi1"   "H2-DMb1" "Cd74"    "Laptm5"  "Ly86"   
[15] "Cd53"    "Mrc1"    "H2-DMa"  "Cd52"    "Pld4"    "Plek"    "Cybb"   
[22] "C1qb"    "Ms4a7"   "Emr1"    "C1qc"    "C1qa"    "Lilrb4"  "Csf1r"  
[29] "Bcl2a1b" "C5ar1"  
[1] ""
[1] ""
[1] "PC3"
 [1] "Cd34"    "Cst3"    "Fxyd5"   "Scara5"  "Pi16"    "Clec3b"  "Mfap5"  
 [8] "Srgn"    "Emp3"    "Sdpr"    "Laptm5"  "Krtdap"  "Slc43a3" "Tyrobp" 
[15] "Cd74"    "Cd52"    "Lbp"     "Lum"     "Lmo2"    "Fcer1g"  "Htra3"  
[22] "H2-DMa"  "H2-Eb1"  "Igfbp4"  "Fbln1"   "Plbd1"   "Rbp1"    "Itih5"  
[29] "Rac2"    "H2-Aa"  
[1] ""
 [1] "Ly6d"          "Wfdc2"         "Aqp3"          "Spint2"       
 [5] "Krt7"          "Igfbp2"        "Perp"          "Krt15"        
 [9] "Krt19"         "Sprr1a"        "Cldn7"         "Krt8"         
[13] "Mal"           "1110032A04Rik" "Cldn4"         "Gsto1"        
[17] "Upk1a"         "Krt5"          "Ezr"           "Akr1b8"       
[21] "Acaa1b"        "Ctse"          "Cdh1"          "Krt23"        
[25] "Vsig2"         "Avpi1"         "Aldh3a1"       "Tacstd2"      
[29] "Tpm2"          "1600029D21Rik"
[1] ""
[1] ""
[1] "PC4"
 [1] "Scara5"    "Clec3b"    "Pi16"      "Mfap5"     "Gsn"      
 [6] "Krtdap"    "Lbp"       "Lum"       "Sfrp1"     "Abi3bp"   
[11] "Fbln1"     "Cd55"      "Entpd2"    "Wfdc2"     "Ccdc80"   
[16] "Serpina3n" "Krt7"      "Cldn7"     "Htra3"     "Perp"     
[21] "Arap1"     "Id2"       "Ly6d"      "Col8a1"    "Krt19"    
[26] "Npy1r"     "Igfbp2"    "Plxdc2"    "Cdh1"      "Tnxb"     
[1] ""
 [1] "Col4a2"        "Col4a1"        "Cd200"         "Egfl7"        
 [5] "Ifi27l1"       "Ptprb"         "Gpr116"        "Emcn"         
 [9] "Eltd1"         "Tnc"           "Pecam1"        "Gimap6"       
[13] "Car3"          "Irf1"          "Cdh5"          "Cxcl12"       
[17] "Flt1"          "Podxl"         "Gadd45b"       "Cd93"         
[21] "Mndal"         "Arhgap31"      "Ecscr"         "Tsc22d1"      
[25] "Mmrn2"         "Ifi203"        "C130074G19Rik" "Srgn"         
[29] "Pltp"          "Pde4b"        
[1] ""
[1] ""
[1] "PC5"
 [1] "Plvap"         "Flt1"          "Pcdh17"        "Emcn"         
 [5] "Gpr116"        "Eltd1"         "Cdh5"          "Rsad2"        
 [9] "Mmrn2"         "Pecam1"        "Ctla2a"        "C130074G19Rik"
[13] "Podxl"         "Egfl7"         "Pde2a"         "Igfbp3"       
[17] "Scarb1"        "Mal"           "Gimap6"        "Jam2"         
[21] "Ptprb"         "St3gal6"       "Gpihbp1"       "Aqp3"         
[25] "Fam101b"       "Krt7"          "Vsig2"         "S1pr1"        
[29] "Wfdc2"         "Cldn4"        
[1] ""
 [1] "Rcan2"   "Nrip2"   "ORF63"   "Pln"     "Des"     "Myh11"   "Ckb"    
 [8] "Cox4i2"  "Pdlim3"  "Filip1l" "Lmod1"   "Crip1"   "Rgs4"    "Acta2"  
[15] "Myl9"    "Sncg"    "Cald1"   "Gucy1b3" "Mrvi1"   "Mustn1"  "Rrad"   
[22] "Rgs5"    "Aspn"    "Bcr"     "S100a4"  "Gucy1a3" "Rasl11a" "Ltbp1"  
[29] "Rbpms2"  "Notch3" 
[1] ""
[1] ""
subtiss <- ProjectPCA(object = subtiss, do.print = FALSE)
# If this fails for your subset, it may be that cells.use is more cells than you have left! Try reducing it.
PCHeatmap(object = subtiss, pc.use = 1:3, cells.use = 250, do.balanced = TRUE, label.columns = FALSE, num.genes = 12)

Later on (in FindClusters and TSNE) you will pick a number of principal components to use. This has the effect of keeping the major directions of variation in the data and, ideally, supressing noise. There is no correct answer to the number to use, but a decent rule of thumb is to go until the plot plateaus.

PCElbowPlot(object = subtiss)

Choose the number of principal components to use.

# Set number of principal components. 
sub.n.pcs = 5

The clustering is performed based on a nearest neighbors graph. Cells that have similar expression will be joined together. The Louvain algorithm looks for groups of cells with high modularity–more connections within the group than between groups. The resolution parameter determines the scale…higher resolution will give more clusters, lower resolution will give fewer.

# Set resolution 
sub.res.used <- 1

subtiss <- FindClusters(object = subtiss, reduction.type = "pca", dims.use = 1:sub.n.pcs, 
    resolution = sub.res.used, ,print.output = 0, save.SNN = TRUE)

To visualize

# If cells are too spread out, you can raise the perplexity. If you have few cells, try a lower perplexity (but never less than 10).
subtiss <- RunTSNE(object = subtiss, dims.use = 1:sub.n.pcs, seed.use = 10, perplexity=20)
# note that you can set do.label=T to help label individual clusters
TSNEPlot(object = subtiss, do.label = T)

subtiss.markers <- FindAllMarkers(object = subtiss, only.pos = TRUE, min.pct = 0.25, thresh.use = 0.25)
subtiss.markers %>% group_by(cluster) %>% top_n(6, avg_diff)

Check expression of genes of interset.

genes_to_check = c('Alb', 'Cyp2f2', 'Cyp2e1', 'Hamp', 'Glul', 'Ass1', 'Axin2', 'Igfbp2')

FeaturePlot(subtiss, genes_to_check, pt.size = 1)

Dotplots let you see the intensity of exppression and the fraction of cells expressing for each of your genes of interest.

# To change the y-axis to show raw counts, add use.raw = T.
DotPlot(subtiss, genes_to_check, plot.legend = T)

How big are the clusters?

table(subtiss@ident)

  0   1   2   3   4   5   6 
167 117  93  74  69  35  13 

Checking for batch effects

Color by metadata, like plate barcode, to check for batch effects.

TSNEPlot(object = subtiss, do.return = TRUE, group.by = "channel")

Print a table showing the count of cells in each identity category from each plate.

table(as.character(subtiss@ident), as.character(subtiss@meta.data$channel))
   
    10X_P7_7
  0      167
  1      117
  2       93
  3       74
  4       69
  5       35
  6       13

Save the Robject for later

When you save the annotated tissue, please give it a name.

filename = here('00_data_ingest', '04_tissue_robj_generated', 
                    paste0(tissue_of_interest, "_droplet_seurat_tiss.Robj"))
print(filename)
[1] "/Users/olgabot/code/tabula-muris/00_data_ingest/04_tissue_robj_generated/Bladder_droplet_seurat_tiss.Robj"
save(tiss, file=filename)
# To reload a saved object
# filename = here('00_data_ingest', '04_tissue_robj_generated', 
#                      paste0(tissue_of_interest, "_seurat_tiss.Robj"))
# load(file=filename)

Export the final metadata

So that Biohub can easily combine all your annotations, please export them as a simple csv.

head(tiss@meta.data)
filename = here('00_data_ingest', '03_tissue_annotation_csv', 
                    paste0(tissue_of_interest, "_droplet_annotation.csv"))
write.csv(tiss@meta.data[,c('channel','annotation','cell_ontology_id')], file=filename)
LS0tCiB0aXRsZTogIkJsYWRkZXIgRHJvcGxldCBOb3RlYm9vayIKIG91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCkVudGVyIHRoZSBkaXJlY3Rvcnkgb2YgdGhlIG1hY2EgZm9sZGVyIG9uIHlvdXIgZHJpdmUgYW5kIHRoZSBuYW1lIG9mIHRoZSB0aXNzdWUgeW91IHdhbnQgdG8gYW5hbHl6ZS4KCmBgYHtyfQp0aXNzdWVfb2ZfaW50ZXJlc3QgPSAiQmxhZGRlciIKYGBgCgpMb2FkIHRoZSByZXF1aXNpdGUgcGFja2FnZXMgYW5kIHNvbWUgYWRkaXRpb25hbCBoZWxwZXIgZnVuY3Rpb25zLgoKYGBge3J9CmxpYnJhcnkoaGVyZSkKbGlicmFyeSh1c2VmdWwpCmxpYnJhcnkoU2V1cmF0KQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KE1hdHJpeCkKCnNhdmVfZGlyID0gaGVyZSgnMDBfZGF0YV9pbmdlc3QnLCAndGlzc3VlX3JvYmonKQpkcm9wbGV0X2RhdGFfZGlyID0gaGVyZSgnMDBfZGF0YV9pbmdlc3QnLCAnZHJvcGxldF9yYXdfZGF0YScpCmBgYAoKCgpgYGB7cn0KIyByZWFkIHRoZSBtZXRhZGF0YSB0byBnZXQgdGhlIHBsYXRlcyB3ZSB3YW50CmRyb3BsZXRfbWV0YWRhdGFfZmlsZW5hbWUgPSBoZXJlKCcwMF9kYXRhX2luZ2VzdCcsICdkcm9wbGV0X3Jhd19kYXRhJywgJ21ldGFkYXRhX2Ryb3BsZXQuY3N2JykKCmRyb3BsZXRfbWV0YWRhdGEgPC0gcmVhZC5jc3YoZHJvcGxldF9tZXRhZGF0YV9maWxlbmFtZSwgc2VwPSIsIiwgaGVhZGVyID0gVFJVRSkKY29sbmFtZXMoZHJvcGxldF9tZXRhZGF0YSlbMV0gPC0gImNoYW5uZWwiCmRyb3BsZXRfbWV0YWRhdGEKYGBgCgpTdWJzZXQgdGhlIG1ldGFkYXRhIG9uIHRoZSB0aXNzdWUuCgpgYGB7cn0KdGlzc3VlX21ldGFkYXRhID0gZmlsdGVyKGRyb3BsZXRfbWV0YWRhdGEsIHRpc3N1ZSA9PSB0aXNzdWVfb2ZfaW50ZXJlc3QpWyxjKCdjaGFubmVsJywndGlzc3VlJywnc3VidGlzc3VlJywnbW91c2Uuc2V4JywgJ21vdXNlLmlkJyldCnRpc3N1ZV9tZXRhZGF0YQpgYGAKCgpVc2Ugb25seSB0aGUgbWV0YWRhdGEgcm93cyBjb3JyZXNwb25kaW5nIHRvIEJsYWRkZXIgcGxhdGVzLiBNYWtlIGEgcGxhdGUgYmFyY29kZSBkYXRhZnJhbWUgdG8gImV4cGFuZCIgdGhlIHBlci1wbGF0ZSBtZXRhZGF0YSB0byBiZSBwZXItY2VsbC4KCmBgYHtyfQojIExvYWQgdGhlIGdlbmUgbmFtZXMgYW5kIHNldCB0aGUgbWV0YWRhdGEgY29sdW1ucyBieSBvcGVuaW5nIHRoZSBmaXJzdCBmaWxlCgpzdWJmb2xkZXIgPSBwYXN0ZTAodGlzc3VlX29mX2ludGVyZXN0LCAnLScsIHRpc3N1ZV9tZXRhZGF0YSRjaGFubmVsWzFdKQpyYXcuZGF0YSA8LSBSZWFkMTBYKGRhdGEuZGlyID0gaGVyZSgnMDBfZGF0YV9pbmdlc3QnLCAnZHJvcGxldF9yYXdfZGF0YScsICdkcm9wbGV0Jywgc3ViZm9sZGVyKSkKY29sbmFtZXMocmF3LmRhdGEpIDwtIGxhcHBseShjb2xuYW1lcyhyYXcuZGF0YSksIGZ1bmN0aW9uKHgpIHBhc3RlMCh0aXNzdWVfbWV0YWRhdGEkY2hhbm5lbFsxXSwgJ18nLCB4KSkKbWV0YS5kYXRhID0gZGF0YS5mcmFtZShyb3cubmFtZXMgPSBjb2xuYW1lcyhyYXcuZGF0YSkpCm1ldGEuZGF0YVsnY2hhbm5lbCddID0gdGlzc3VlX21ldGFkYXRhJGNoYW5uZWxbMV0KCmlmIChsZW5ndGgodGlzc3VlX21ldGFkYXRhJGNoYW5uZWwpID4gMSl7CiAgIyBTb21lIHRpc3N1ZXMsIGxpa2UgVGh5bXVzIGFuZCBIZWFydCBoYWQgb25seSBvbmUgY2hhbm5lbAogIGZvcihpIGluIDI6bnJvdyh0aXNzdWVfbWV0YWRhdGEpKXsKICAgIHN1YmZvbGRlciA9IHBhc3RlMCh0aXNzdWVfb2ZfaW50ZXJlc3QsICctJywgdGlzc3VlX21ldGFkYXRhJGNoYW5uZWxbaV0pCiAgICBuZXcuZGF0YSA8LSBSZWFkMTBYKGRhdGEuZGlyID0gaGVyZSgnMDBfZGF0YV9pbmdlc3QnLCAnZHJvcGxldF9yYXdfZGF0YScsICdkcm9wbGV0Jywgc3ViZm9sZGVyKSkKICAgIGNvbG5hbWVzKG5ldy5kYXRhKSA8LSBsYXBwbHkoY29sbmFtZXMobmV3LmRhdGEpLCBmdW5jdGlvbih4KSBwYXN0ZTAodGlzc3VlX21ldGFkYXRhJGNoYW5uZWxbaV0sICdfJywgeCkpCiAgICAKICAgIG5ldy5tZXRhZGF0YSA9IGRhdGEuZnJhbWUocm93Lm5hbWVzID0gY29sbmFtZXMobmV3LmRhdGEpKQogICAgbmV3Lm1ldGFkYXRhWydjaGFubmVsJ10gPSB0aXNzdWVfbWV0YWRhdGEkY2hhbm5lbFtpXQogICAgCiAgICByYXcuZGF0YSA9IGNiaW5kKHJhdy5kYXRhLCBuZXcuZGF0YSkKICAgIG1ldGEuZGF0YSA9IHJiaW5kKG1ldGEuZGF0YSwgbmV3Lm1ldGFkYXRhKQogIH0KfQoKcm5hbWVzID0gcm93Lm5hbWVzKG1ldGEuZGF0YSkKbWV0YS5kYXRhIDwtIG1lcmdlKG1ldGEuZGF0YSwgdGlzc3VlX21ldGFkYXRhLCBzb3J0ID0gRikKcm93Lm5hbWVzKG1ldGEuZGF0YSkgPC0gcm5hbWVzCmRpbShyYXcuZGF0YSkKY29ybmVyKHJhdy5kYXRhKQpoZWFkKG1ldGEuZGF0YSkKYGBgCgpQcm9jZXNzIHRoZSByYXcgZGF0YSBhbmQgbG9hZCBpdCBpbnRvIHRoZSBTZXVyYXQgb2JqZWN0LgoKYGBge3J9CiMgRmluZCBFUkNDJ3MsIGNvbXB1dGUgdGhlIHBlcmNlbnQgRVJDQywgYW5kIGRyb3AgdGhlbSBmcm9tIHRoZSByYXcgZGF0YS4KZXJjY3MgPC0gZ3JlcChwYXR0ZXJuID0gIl5FUkNDLSIsIHggPSByb3duYW1lcyh4ID0gcmF3LmRhdGEpLCB2YWx1ZSA9IFRSVUUpCnBlcmNlbnQuZXJjYyA8LSBNYXRyaXg6OmNvbFN1bXMocmF3LmRhdGFbZXJjY3MsIF0pL01hdHJpeDo6Y29sU3VtcyhyYXcuZGF0YSkKZXJjYy5pbmRleCA8LSBncmVwKHBhdHRlcm4gPSAiXkVSQ0MtIiwgeCA9IHJvd25hbWVzKHggPSByYXcuZGF0YSksIHZhbHVlID0gRkFMU0UpCnJhdy5kYXRhIDwtIHJhdy5kYXRhWy1lcmNjLmluZGV4LF0KCiMgQ3JlYXRlIHRoZSBTZXVyYXQgb2JqZWN0IHdpdGggYWxsIHRoZSBkYXRhCnRpc3MgPC0gQ3JlYXRlU2V1cmF0T2JqZWN0KHJhdy5kYXRhID0gcmF3LmRhdGEsIHByb2plY3QgPSB0aXNzdWVfb2ZfaW50ZXJlc3QsIAogICAgICAgICAgICAgICAgICAgIG1pbi5jZWxscyA9IDUsIG1pbi5nZW5lcyA9IDUpCgp0aXNzIDwtIEFkZE1ldGFEYXRhKG9iamVjdCA9IHRpc3MsIG1ldGEuZGF0YSkKdGlzcyA8LSBBZGRNZXRhRGF0YShvYmplY3QgPSB0aXNzLCBwZXJjZW50LmVyY2MsIGNvbC5uYW1lID0gInBlcmNlbnQuZXJjYyIpCgojIENyZWF0ZSBtZXRhZGF0YSBjb2x1bW5zIGZvciBhbm5vdGF0aW9ucyBhbmQgc3ViYW5ub3RhdGlvbnMKdGlzc0BtZXRhLmRhdGFbLCdhbm5vdGF0aW9uJ10gPC0gTkEKdGlzc0BtZXRhLmRhdGFbLCdzdWJhbm5vdGF0aW9uJ10gPC0gTkEKYGBgCgoKQ2FsY3VsYXRlIHBlcmNlbnQgcmlib3NvbWFsIGdlbmVzLgoKYGBge3J9CnJpYm8uZ2VuZXMgPC0gZ3JlcChwYXR0ZXJuID0gIl5ScFtzbF1bWzpkaWdpdDpdXSIsIHggPSByb3duYW1lcyh4ID0gdGlzc0BkYXRhKSwgdmFsdWUgPSBUUlVFKQpwZXJjZW50LnJpYm8gPC0gTWF0cml4Ojpjb2xTdW1zKHRpc3NAcmF3LmRhdGFbcmliby5nZW5lcywgXSkvTWF0cml4Ojpjb2xTdW1zKHRpc3NAcmF3LmRhdGEpCnRpc3MgPC0gQWRkTWV0YURhdGEob2JqZWN0ID0gdGlzcywgbWV0YWRhdGEgPSBwZXJjZW50LnJpYm8sIGNvbC5uYW1lID0gInBlcmNlbnQucmlibyIpCmBgYAoKQSBzYW5pdHkgY2hlY2s6IGdlbmVzIHBlciBjZWxsIHZzIHJlYWRzIHBlciBjZWxsLgoKYGBge3J9CkdlbmVQbG90KG9iamVjdCA9IHRpc3MsIGdlbmUxID0gIm5VTUkiLCBnZW5lMiA9ICJuR2VuZSIsIHVzZS5yYXc9VCkKYGBgCgpGaWx0ZXIgb3V0IGNlbGxzIHdpdGggZmV3IHJlYWRzIGFuZCBmZXcgZ2VuZXMuCgpgYGB7cn0KdGlzcyA8LSBGaWx0ZXJDZWxscyhvYmplY3QgPSB0aXNzLCBzdWJzZXQubmFtZXMgPSBjKCJuR2VuZSIsICJuVU1JIiksIAogICAgbG93LnRocmVzaG9sZHMgPSBjKDUwMCwgMTAwMCksIGhpZ2gudGhyZXNob2xkcyA9IGMoMjUwMDAsIDUwMDAwMDApKQpgYGAKCgpOb3JtYWxpemUgdGhlIGRhdGEsIHRoZW4gcmVncmVzcyBvdXQgY29ycmVsYXRpb24gd2l0aCB0b3RhbCByZWFkcwpgYGB7cn0KdGlzcyA8LSBOb3JtYWxpemVEYXRhKG9iamVjdCA9IHRpc3MpCnRpc3MgPC0gU2NhbGVEYXRhKG9iamVjdCA9IHRpc3MsIHZhcnMudG8ucmVncmVzcyA9IGMoIm5VTUkiLCAicGVyY2VudC5yaWJvIiwiUm40NXMiKSkKdGlzcyA8LSBGaW5kVmFyaWFibGVHZW5lcyhvYmplY3QgPSB0aXNzLCBkby5wbG90ID0gVFJVRSwgeC5oaWdoLmN1dG9mZiA9IEluZiwgeS5jdXRvZmYgPSAwLjUpCmBgYAoKClJ1biBQcmluY2lwYWwgQ29tcG9uZW50IEFuYWx5c2lzLgpgYGB7cn0KdGlzcyA8LSBSdW5QQ0Eob2JqZWN0ID0gdGlzcywgZG8ucHJpbnQgPSBGQUxTRSkKdGlzcyA8LSBQcm9qZWN0UENBKG9iamVjdCA9IHRpc3MsIGRvLnByaW50ID0gRkFMU0UpCmBgYAoKYGBge3IsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTh9ClBDSGVhdG1hcChvYmplY3QgPSB0aXNzLCBwYy51c2UgPSAxOjMsIGNlbGxzLnVzZSA9IDUwMCwgZG8uYmFsYW5jZWQgPSBUUlVFLCBsYWJlbC5jb2x1bW5zID0gRkFMU0UsIG51bS5nZW5lcyA9IDgpCmBgYAoKTGF0ZXIgb24gKGluIEZpbmRDbHVzdGVycyBhbmQgVFNORSkgeW91IHdpbGwgcGljayBhIG51bWJlciBvZiBwcmluY2lwYWwgY29tcG9uZW50cyB0byB1c2UuIFRoaXMgaGFzIHRoZSBlZmZlY3Qgb2Yga2VlcGluZyB0aGUgbWFqb3IgZGlyZWN0aW9ucyBvZiB2YXJpYXRpb24gaW4gdGhlIGRhdGEgYW5kLCBpZGVhbGx5LCBzdXByZXNzaW5nIG5vaXNlLiBUaGVyZSBpcyBubyBjb3JyZWN0IGFuc3dlciB0byB0aGUgbnVtYmVyIHRvIHVzZSwgYnV0IGEgZGVjZW50IHJ1bGUgb2YgdGh1bWIgaXMgdG8gZ28gdW50aWwgdGhlIHBsb3QgcGxhdGVhdXMuCgpgYGB7cn0KUENFbGJvd1Bsb3Qob2JqZWN0ID0gdGlzcykKYGBgCgpDaG9vc2UgdGhlIG51bWJlciBvZiBwcmluY2lwYWwgY29tcG9uZW50cyB0byB1c2UuCmBgYHtyfQojIFNldCBudW1iZXIgb2YgcHJpbmNpcGFsIGNvbXBvbmVudHMuIApuLnBjcyA9IDE1CmBgYAoKClRoZSBjbHVzdGVyaW5nIGlzIHBlcmZvcm1lZCBiYXNlZCBvbiBhIG5lYXJlc3QgbmVpZ2hib3JzIGdyYXBoLiBDZWxscyB0aGF0IGhhdmUgc2ltaWxhciBleHByZXNzaW9uIHdpbGwgYmUgam9pbmVkIHRvZ2V0aGVyLiBUaGUgTG91dmFpbiBhbGdvcml0aG0gbG9va3MgZm9yIGdyb3VwcyBvZiBjZWxscyB3aXRoIGhpZ2ggbW9kdWxhcml0eS0tbW9yZSBjb25uZWN0aW9ucyB3aXRoaW4gdGhlIGdyb3VwIHRoYW4gYmV0d2VlbiBncm91cHMuIFRoZSByZXNvbHV0aW9uIHBhcmFtZXRlciBkZXRlcm1pbmVzIHRoZSBzY2FsZS4uLmhpZ2hlciByZXNvbHV0aW9uIHdpbGwgZ2l2ZSBtb3JlIGNsdXN0ZXJzLCBsb3dlciByZXNvbHV0aW9uIHdpbGwgZ2l2ZSBmZXdlci4KCkZvciB0aGUgdG9wLWxldmVsIGNsdXN0ZXJpbmcsIGFpbSB0byB1bmRlci1jbHVzdGVyIGluc3RlYWQgb2Ygb3Zlci1jbHVzdGVyLiBJdCB3aWxsIGJlIGVhc3kgdG8gc3Vic2V0IGdyb3VwcyBhbmQgZnVydGhlciBhbmFseXplIHRoZW0gYmVsb3cuCgpgYGB7cn0KIyBTZXQgcmVzb2x1dGlvbiAKcmVzLnVzZWQgPC0gMS4wCgp0aXNzIDwtIEZpbmRDbHVzdGVycyhvYmplY3QgPSB0aXNzLCByZWR1Y3Rpb24udHlwZSA9ICJwY2EiLCBkaW1zLnVzZSA9IDE6bi5wY3MsIAogICAgcmVzb2x1dGlvbiA9IHJlcy51c2VkLCBwcmludC5vdXRwdXQgPSAwLCBzYXZlLlNOTiA9IFRSVUUpCmBgYAoKClRvIHZpc3VhbGl6ZSAKYGBge3J9CiMgSWYgY2VsbHMgYXJlIHRvbyBzcHJlYWQgb3V0LCB5b3UgY2FuIHJhaXNlIHRoZSBwZXJwbGV4aXR5LiBJZiB5b3UgaGF2ZSBmZXcgY2VsbHMsIHRyeSBhIGxvd2VyIHBlcnBsZXhpdHkgKGJ1dCBuZXZlciBsZXNzIHRoYW4gMTApLgp0aXNzIDwtIFJ1blRTTkUob2JqZWN0ID0gdGlzcywgZGltcy51c2UgPSAxOm4ucGNzLCBzZWVkLnVzZSA9IDEwLCBwZXJwbGV4aXR5PTMwLCBkaW0uZW1iZWQgPSAyKQpgYGAKCmBgYHtyfQojIG5vdGUgdGhhdCB5b3UgY2FuIHNldCBkby5sYWJlbD1UIHRvIGhlbHAgbGFiZWwgaW5kaXZpZHVhbCBjbHVzdGVycwpUU05FUGxvdChvYmplY3QgPSB0aXNzLCBkby5sYWJlbCA9IFQpCmBgYAoKQ2hlY2sgZXhwcmVzc2lvbiBvZiBnZW5lcyBvZiBpbnRlcnNldC4KCmBgYHtyLCBlY2hvPUZBTFNFLCBmaWcuaGVpZ2h0PTEyLCBmaWcud2lkdGg9OH0KZ2VuZXNfdG9fY2hlY2sgPSBjKCdFcGNhbScsJ1VwazFiJywgJ1VwazNhJywnR3JobDMnLCAnS3J0NScsICdLcnQxNCcsICdEY24nLCAnQ29sMWExJywnQ29sOGExJywgJ1BlY2FtMScsICdDZDE0JyApCiNnZW5lc190b19jaGVjayA9IGMoJ0FsYicsICdDeXAyZjInLCAnQ3lwMiwgJ0tydDIwJykKCkZlYXR1cmVQbG90KHRpc3MsIGdlbmVzX3RvX2NoZWNrLCBwdC5zaXplID0gMSwgbkNvbCA9IDMpCmBgYAoKYGBge3J9ClZsblBsb3QodGlzcywgZ2VuZXNfdG9fY2hlY2spCmBgYAoKCkRvdHBsb3RzIGxldCB5b3Ugc2VlIHRoZSBpbnRlbnNpdHkgb2YgZXhwcHJlc3Npb24gYW5kIHRoZSBmcmFjdGlvbiBvZiBjZWxscyBleHByZXNzaW5nIGZvciBlYWNoIG9mIHlvdXIgZ2VuZXMgb2YgaW50ZXJlc3QuCgpgYGB7ciwgZWNobz1GQUxTRSwgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9OH0KIyBUbyBjaGFuZ2UgdGhlIHktYXhpcyB0byBzaG93IHJhdyBjb3VudHMsIGFkZCB1c2UucmF3ID0gVC4KRG90UGxvdCh0aXNzLCBnZW5lc190b19jaGVjaywgcGxvdC5sZWdlbmQgPSBUKQpgYGAKCkhvdyBiaWcgYXJlIHRoZSBjbHVzdGVycz8KYGBge3J9CnRhYmxlKHRpc3NAaWRlbnQpCmBgYAoKCldoaWNoIG1hcmtlcnMgaWRlbnRpZnkgYSBzcGVjaWZpYyBjbHVzdGVyPwoKYGBge3J9CmNsdXN0Lm1hcmtlcnMgPC0gRmluZE1hcmtlcnMob2JqZWN0ID0gdGlzcywgaWRlbnQuMSA9IDIsIGlkZW50LjIgPSAxLCBvbmx5LnBvcyA9IFRSVUUsIG1pbi5wY3QgPSAwLjI1LCB0aHJlc2gudXNlID0gMC4yNSkKYGBgCgoKYGBge3J9CnByaW50KHggPSBoZWFkKHg9IGNsdXN0Lm1hcmtlcnMsIG4gPSAxMCkpCmBgYAoKWW91IGNhbiBhbHNvIGNvbXB1dGUgYWxsIG1hcmtlcnMgZm9yIGFsbCBjbHVzdGVycyBhdCBvbmNlLiBUaGlzIG1heSB0YWtlIHNvbWUgdGltZS4KYGBge3J9CnRpc3MubWFya2VycyA8LSBGaW5kQWxsTWFya2VycyhvYmplY3QgPSB0aXNzLCBvbmx5LnBvcyA9IFRSVUUsIG1pbi5wY3QgPSAwLjI1LCB0aHJlc2gudXNlID0gMC4yNSkKYGBgCgpEaXNwbGF5IHRoZSB0b3AgbWFya2VycyB5b3UgY29tcHV0ZWQgYWJvdmUuCmBgYHtyfQp0aXNzLm1hcmtlcnMgJT4lIGdyb3VwX2J5KGNsdXN0ZXIpICU+JSB0b3BfbigyNSwgYXZnX2RpZmYpCmBgYAoKYGBge3IsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTh9CiMgVG8gY2hhbmdlIHRoZSB5LWF4aXMgdG8gc2hvdyByYXcgY291bnRzLCBhZGQgdXNlLnJhdyA9IFQuCkRvdFBsb3QodGlzcywgZ2VuZXNfdG9fY2hlY2ssIHBsb3QubGVnZW5kID0gVCkKYGBgCgpgYGB7cn0KdGlzcz0gQnVpbGRDbHVzdGVyVHJlZSh0aXNzKQpgYGAKCmBgYHtyfQpOb2RlMThfbWFya2VycyA9IEZpbmRBbGxNYXJrZXJzTm9kZSh0aXNzLCBub2RlID0gMTgpCmBgYAoKYGBge3J9Ck5vZGUxOF9tYXJrZXJzICU+JSBncm91cF9ieShjbHVzdGVyKSAlPiUgdG9wX24oMTUsIGF2Z19kaWZmKQpgYGAKCgojIyBBc3NpZ25pbmcgY2VsbCB0eXBlIGlkZW50aXR5IHRvIGNsdXN0ZXJzCgpBdCBhIGNvYXJzZSBsZXZlbCwgd2UgY2FuIHVzZSBjYW5vbmljYWwgbWFya2VycyB0byBtYXRjaCB0aGUgdW5iaWFzZWQgY2x1c3RlcmluZyB0byBrbm93biBjZWxsIHR5cGVzOgoKCmBgYHtyfQojIHN0YXNoIGN1cnJlbnQgY2x1c3RlciBJRHMKdGlzcyA8LSBTdGFzaElkZW50KG9iamVjdCA9IHRpc3MsIHNhdmUubmFtZSA9ICJjbHVzdGVyLmlkcyIpCgojIGVudW1lcmF0ZSBjdXJyZW50IGNsdXN0ZXIgSURzIGFuZCB0aGUgbGFiZWxzIGZvciB0aGVtCmNsdXN0ZXIuaWRzIDwtIGMoMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSkKYW5ub3RhdGlvbiA8LSBjKCJtZXNlbmNoeW1hbCBjZWxsIiwgImJsYWRkZXIgY2VsbCIgLCAibWVzZW5jaHltYWwgY2VsbCIsICJibGFkZGVyIGNlbGwiLCAiYmFzYWwgY2VsbCBvZiB1cm90aGVsaXVtIiwgImJsYWRkZXIgY2VsbCIsICJtZXNlbmNoeW1hbCBjZWxsIiwgIm1lc2VuY2h5bWFsIGNlbGwiLCAiZW5kb3RoZWxpYWwgY2VsbCIsICJsZXVrb2N5dGUiKQpjZWxsX29udG9sb2d5X2lkIDwtIGMoIkNMOjAwMDgwMTkiLCAiQ0w6MTAwMTMxOSIgLCAiQ0w6MDAwODAxOSIsICJDTDoxMDAxMzE5IiwgIkNMOjEwMDA0ODYiLCAiQ0w6MTAwMTMxOSIsICJDTDowMDA4MDE5IiwgIkNMOjAwMDgwMTkiLCAiQ0w6MDAwMDExNSIsICJDTDowMDAwNzM4IikKCnRpc3NAbWV0YS5kYXRhWywnYW5ub3RhdGlvbiddIDwtIHBseXI6Om1hcHZhbHVlcyh4ID0gdGlzc0BpZGVudCwgZnJvbSA9IGNsdXN0ZXIuaWRzLCB0byA9IGFubm90YXRpb24pCnRpc3NAbWV0YS5kYXRhWywnY2VsbF9vbnRvbG9neV9pZCddIDwtIHBseXI6Om1hcHZhbHVlcyh4ID0gdGlzc0BpZGVudCwgZnJvbSA9IGNsdXN0ZXIuaWRzLCB0byA9IGNlbGxfb250b2xvZ3lfaWQpCgp0aXNzQG1ldGEuZGF0YVt0aXNzQGNlbGwubmFtZXMsJ2Fubm90YXRpb24nXSA8LSBhcy5jaGFyYWN0ZXIodGlzc0BtZXRhLmRhdGEkYW5ub3RhdGlvbikKdGlzc0BtZXRhLmRhdGFbdGlzc0BjZWxsLm5hbWVzLCdjZWxsX29udG9sb2d5X2lkJ10gPC0gYXMuY2hhcmFjdGVyKHRpc3NAbWV0YS5kYXRhJGNlbGxfb250b2xvZ3lfaWQpCgpUU05FUGxvdChvYmplY3QgPSB0aXNzLCBkby5sYWJlbCA9IFRSVUUsIHB0LnNpemUgPSAwLjUsIGdyb3VwLmJ5PSdhbm5vdGF0aW9uJykKYGBgCgoKIyMgQ2hlY2tpbmcgZm9yIGJhdGNoIGVmZmVjdHMKCgpDb2xvciBieSBtZXRhZGF0YSwgbGlrZSBwbGF0ZSBiYXJjb2RlLCB0byBjaGVjayBmb3IgYmF0Y2ggZWZmZWN0cy4KYGBge3J9ClRTTkVQbG90KG9iamVjdCA9IHRpc3MsIGRvLnJldHVybiA9IFRSVUUsIGdyb3VwLmJ5ID0gImNoYW5uZWwiKQpgYGAKCmBgYHtyfQpUU05FUGxvdChvYmplY3QgPSB0aXNzLCBkby5yZXR1cm4gPSBUUlVFLCBncm91cC5ieSA9ICJtb3VzZS5zZXgiKQpgYGAKClByaW50IGEgdGFibGUgc2hvd2luZyB0aGUgY291bnQgb2YgY2VsbHMgaW4gZWFjaCBpZGVudGl0eSBjYXRlZ29yeSBmcm9tIGVhY2ggcGxhdGUuCgpgYGB7cn0KdGFibGUoYXMuY2hhcmFjdGVyKHRpc3NAaWRlbnQpLCBhcy5jaGFyYWN0ZXIodGlzc0BtZXRhLmRhdGEkY2hhbm5lbCkpCmBgYAoKYGBge3J9CnRhYmxlKGFzLmNoYXJhY3Rlcih0aXNzQGlkZW50KSwgYXMuY2hhcmFjdGVyKHRpc3NAbWV0YS5kYXRhJG1vdXNlLmlkKSkKYGBgCgoKIyBTdWJzZXQgYW5kIGl0ZXJhdGUKCldlIGNhbiByZXBlYXQgdGhlIGFib3ZlIGFuYWx5c2lzIG9uIGEgc3Vic2V0IG9mIGNlbGxzLCBkZWZpbmVkIHVzaW5nIGNsdXN0ZXIgSURzIG9yIHNvbWUgb3RoZXIgbWV0YWRhdGEuIFRoaXMgaXMgYSBnb29kIHdheSB0byBkcmlsbCBkb3duIGFuZCBmaW5kIHN1YnN0cnVjdHVyZS4KCiMjIEZpcnN0IHN1YnNldAoKYGBge3J9CiMgU3Vic2V0IGRhdGEgYmFzZWQgb24gY2x1c3RlciBpZApzdWJ0aXNzIDwtIFN1YnNldERhdGEob2JqZWN0ID0gdGlzcywgaWRlbnQudXNlID0gYygzKSwgZG8uY2VudGVyID0gRiwgZG8uc2NhbGUgPSBGLCBjZWxscy51c2UgPSApCgojIFRvIHN1YnNldCBkYXRhIGJhc2VkIG9uIGFubm90YXRpb24gb3Igb3RoZXIgbWV0YWRhdGEsIHlvdSBjYW4gZXhwbGljaXRseSBwYXNzIGNlbGwgbmFtZXMKCmNlbGxzLnRvLnVzZSA9IHRpc3NAY2VsbC5uYW1lc1t3aGljaCh0aXNzQG1ldGEuZGF0YSRtb3VzZS5zZXggPT0gJ0YnKV0Kc3VidGlzcyA8LSBTdWJzZXREYXRhKG9iamVjdCA9IHRpc3MsIGNlbGxzLnVzZSA9IGNlbGxzLnRvLnVzZSwgZG8uY2VudGVyID0gRiwgZG8uc2NhbGUgPSBGKQpgYGAKCmBgYHtyfQpzdWJ0aXNzIDwtIE5vcm1hbGl6ZURhdGEob2JqZWN0ID0gc3VidGlzcykKc3VidGlzcyA8LSBTY2FsZURhdGEob2JqZWN0ID0gc3VidGlzcywgdmFycy50by5yZWdyZXNzID0gYygiblVNSSIsICJwZXJjZW50LnJpYm8iLCJSbjQ1cyIpKQpgYGAKClJ1biBQcmluY2lwYWwgQ29tcG9uZW50IEFuYWx5c2lzLgoKYGBge3J9CnN1YnRpc3MgPC0gRmluZFZhcmlhYmxlR2VuZXMob2JqZWN0ID0gc3VidGlzcywgZG8ucGxvdCA9IFRSVUUsIHguaGlnaC5jdXRvZmYgPSBJbmYsIHkuY3V0b2ZmID0gMC44KQpzdWJ0aXNzIDwtIFJ1blBDQShvYmplY3QgPSBzdWJ0aXNzLCBwY3MuY29tcHV0ZSA9IDIwLCB3ZWlnaHQuYnkudmFyID0gRikKc3VidGlzcyA8LSBQcm9qZWN0UENBKG9iamVjdCA9IHN1YnRpc3MsIGRvLnByaW50ID0gRkFMU0UpCmBgYAoKYGBge3J9CiMgSWYgdGhpcyBmYWlscyBmb3IgeW91ciBzdWJzZXQsIGl0IG1heSBiZSB0aGF0IGNlbGxzLnVzZSBpcyBtb3JlIGNlbGxzIHRoYW4geW91IGhhdmUgbGVmdCEgVHJ5IHJlZHVjaW5nIGl0LgpQQ0hlYXRtYXAob2JqZWN0ID0gc3VidGlzcywgcGMudXNlID0gMTozLCBjZWxscy51c2UgPSAyNTAsIGRvLmJhbGFuY2VkID0gVFJVRSwgbGFiZWwuY29sdW1ucyA9IEZBTFNFLCBudW0uZ2VuZXMgPSAxMikKYGBgCgpMYXRlciBvbiAoaW4gRmluZENsdXN0ZXJzIGFuZCBUU05FKSB5b3Ugd2lsbCBwaWNrIGEgbnVtYmVyIG9mIHByaW5jaXBhbCBjb21wb25lbnRzIHRvIHVzZS4gVGhpcyBoYXMgdGhlIGVmZmVjdCBvZiBrZWVwaW5nIHRoZSBtYWpvciBkaXJlY3Rpb25zIG9mIHZhcmlhdGlvbiBpbiB0aGUgZGF0YSBhbmQsIGlkZWFsbHksIHN1cHJlc3Npbmcgbm9pc2UuIFRoZXJlIGlzIG5vIGNvcnJlY3QgYW5zd2VyIHRvIHRoZSBudW1iZXIgdG8gdXNlLCBidXQgYSBkZWNlbnQgcnVsZSBvZiB0aHVtYiBpcyB0byBnbyB1bnRpbCB0aGUgcGxvdCBwbGF0ZWF1cy4KCmBgYHtyfQpQQ0VsYm93UGxvdChvYmplY3QgPSBzdWJ0aXNzKQpgYGAKCkNob29zZSB0aGUgbnVtYmVyIG9mIHByaW5jaXBhbCBjb21wb25lbnRzIHRvIHVzZS4KYGBge3J9CiMgU2V0IG51bWJlciBvZiBwcmluY2lwYWwgY29tcG9uZW50cy4gCnN1Yi5uLnBjcyA9IDUKYGBgCgoKVGhlIGNsdXN0ZXJpbmcgaXMgcGVyZm9ybWVkIGJhc2VkIG9uIGEgbmVhcmVzdCBuZWlnaGJvcnMgZ3JhcGguIENlbGxzIHRoYXQgaGF2ZSBzaW1pbGFyIGV4cHJlc3Npb24gd2lsbCBiZSBqb2luZWQgdG9nZXRoZXIuIFRoZSBMb3V2YWluIGFsZ29yaXRobSBsb29rcyBmb3IgZ3JvdXBzIG9mIGNlbGxzIHdpdGggaGlnaCBtb2R1bGFyaXR5LS1tb3JlIGNvbm5lY3Rpb25zIHdpdGhpbiB0aGUgZ3JvdXAgdGhhbiBiZXR3ZWVuIGdyb3Vwcy4gVGhlIHJlc29sdXRpb24gcGFyYW1ldGVyIGRldGVybWluZXMgdGhlIHNjYWxlLi4uaGlnaGVyIHJlc29sdXRpb24gd2lsbCBnaXZlIG1vcmUgY2x1c3RlcnMsIGxvd2VyIHJlc29sdXRpb24gd2lsbCBnaXZlIGZld2VyLgoKYGBge3J9CiMgU2V0IHJlc29sdXRpb24gCnN1Yi5yZXMudXNlZCA8LSAxCgpzdWJ0aXNzIDwtIEZpbmRDbHVzdGVycyhvYmplY3QgPSBzdWJ0aXNzLCByZWR1Y3Rpb24udHlwZSA9ICJwY2EiLCBkaW1zLnVzZSA9IDE6c3ViLm4ucGNzLCAKICAgIHJlc29sdXRpb24gPSBzdWIucmVzLnVzZWQsICxwcmludC5vdXRwdXQgPSAwLCBzYXZlLlNOTiA9IFRSVUUpCmBgYAoKVG8gdmlzdWFsaXplIApgYGB7cn0KIyBJZiBjZWxscyBhcmUgdG9vIHNwcmVhZCBvdXQsIHlvdSBjYW4gcmFpc2UgdGhlIHBlcnBsZXhpdHkuIElmIHlvdSBoYXZlIGZldyBjZWxscywgdHJ5IGEgbG93ZXIgcGVycGxleGl0eSAoYnV0IG5ldmVyIGxlc3MgdGhhbiAxMCkuCnN1YnRpc3MgPC0gUnVuVFNORShvYmplY3QgPSBzdWJ0aXNzLCBkaW1zLnVzZSA9IDE6c3ViLm4ucGNzLCBzZWVkLnVzZSA9IDEwLCBwZXJwbGV4aXR5PTIwKQpgYGAKCmBgYHtyfQojIG5vdGUgdGhhdCB5b3UgY2FuIHNldCBkby5sYWJlbD1UIHRvIGhlbHAgbGFiZWwgaW5kaXZpZHVhbCBjbHVzdGVycwpUU05FUGxvdChvYmplY3QgPSBzdWJ0aXNzLCBkby5sYWJlbCA9IFQpCmBgYAoKYGBge3J9CnN1YnRpc3MubWFya2VycyA8LSBGaW5kQWxsTWFya2VycyhvYmplY3QgPSBzdWJ0aXNzLCBvbmx5LnBvcyA9IFRSVUUsIG1pbi5wY3QgPSAwLjI1LCB0aHJlc2gudXNlID0gMC4yNSkKYGBgCgpgYGB7cn0Kc3VidGlzcy5tYXJrZXJzICU+JSBncm91cF9ieShjbHVzdGVyKSAlPiUgdG9wX24oNiwgYXZnX2RpZmYpCmBgYAoKQ2hlY2sgZXhwcmVzc2lvbiBvZiBnZW5lcyBvZiBpbnRlcnNldC4KYGBge3J9CmdlbmVzX3RvX2NoZWNrID0gYygnQWxiJywgJ0N5cDJmMicsICdDeXAyZTEnLCAnSGFtcCcsICdHbHVsJywgJ0FzczEnLCAnQXhpbjInLCAnSWdmYnAyJykKCkZlYXR1cmVQbG90KHN1YnRpc3MsIGdlbmVzX3RvX2NoZWNrLCBwdC5zaXplID0gMSkKYGBgCgpEb3RwbG90cyBsZXQgeW91IHNlZSB0aGUgaW50ZW5zaXR5IG9mIGV4cHByZXNzaW9uIGFuZCB0aGUgZnJhY3Rpb24gb2YgY2VsbHMgZXhwcmVzc2luZyBmb3IgZWFjaCBvZiB5b3VyIGdlbmVzIG9mIGludGVyZXN0LgoKYGBge3J9CiMgVG8gY2hhbmdlIHRoZSB5LWF4aXMgdG8gc2hvdyByYXcgY291bnRzLCBhZGQgdXNlLnJhdyA9IFQuCkRvdFBsb3Qoc3VidGlzcywgZ2VuZXNfdG9fY2hlY2ssIHBsb3QubGVnZW5kID0gVCkKYGBgCgpIb3cgYmlnIGFyZSB0aGUgY2x1c3RlcnM/CmBgYHtyfQp0YWJsZShzdWJ0aXNzQGlkZW50KQpgYGAKCiMjIENoZWNraW5nIGZvciBiYXRjaCBlZmZlY3RzCgpDb2xvciBieSBtZXRhZGF0YSwgbGlrZSBwbGF0ZSBiYXJjb2RlLCB0byBjaGVjayBmb3IgYmF0Y2ggZWZmZWN0cy4KYGBge3J9ClRTTkVQbG90KG9iamVjdCA9IHN1YnRpc3MsIGRvLnJldHVybiA9IFRSVUUsIGdyb3VwLmJ5ID0gImNoYW5uZWwiKQpgYGAKClByaW50IGEgdGFibGUgc2hvd2luZyB0aGUgY291bnQgb2YgY2VsbHMgaW4gZWFjaCBpZGVudGl0eSBjYXRlZ29yeSBmcm9tIGVhY2ggcGxhdGUuCgpgYGB7cn0KdGFibGUoYXMuY2hhcmFjdGVyKHN1YnRpc3NAaWRlbnQpLCBhcy5jaGFyYWN0ZXIoc3VidGlzc0BtZXRhLmRhdGEkY2hhbm5lbCkpCmBgYAoKIyBTYXZlIHRoZSBSb2JqZWN0IGZvciBsYXRlcgpXaGVuIHlvdSBzYXZlIHRoZSBhbm5vdGF0ZWQgdGlzc3VlLCBwbGVhc2UgZ2l2ZSBpdCBhIG5hbWUuCgpgYGB7cn0KZmlsZW5hbWUgPSBoZXJlKCcwMF9kYXRhX2luZ2VzdCcsICd0aXNzdWVfc2V1cmF0X3JvYmonLCAKICAgICAgICAgICAgICAgICAgICBwYXN0ZTAodGlzc3VlX29mX2ludGVyZXN0LCAiX2Ryb3BsZXRfc2V1cmF0X3Rpc3MuUm9iaiIpKQpwcmludChmaWxlbmFtZSkKc2F2ZSh0aXNzLCBmaWxlPWZpbGVuYW1lKQpgYGAKCmBgYHtyfQojIFRvIHJlbG9hZCBhIHNhdmVkIG9iamVjdAojIGZpbGVuYW1lID0gaGVyZSgnMDBfZGF0YV9pbmdlc3QnLCAndGlzc3VlX3NldXJhdF9yb2JqJywgCiMgICAgICAgICAgICAgICAgICAgICAgcGFzdGUwKHRpc3N1ZV9vZl9pbnRlcmVzdCwgIl9zZXVyYXRfdGlzcy5Sb2JqIikpCiMgbG9hZChmaWxlPWZpbGVuYW1lKQpgYGAKCgojIEV4cG9ydCB0aGUgZmluYWwgbWV0YWRhdGEKClNvIHRoYXQgQmlvaHViIGNhbiBlYXNpbHkgY29tYmluZSBhbGwgeW91ciBhbm5vdGF0aW9ucywgcGxlYXNlIGV4cG9ydCB0aGVtIGFzIGEgc2ltcGxlIGNzdi4KCmBgYHtyfQpoZWFkKHRpc3NAbWV0YS5kYXRhKQpgYGAKCgpgYGB7cn0KZmlsZW5hbWUgPSBoZXJlKCcwMF9kYXRhX2luZ2VzdCcsICd0aXNzdWVfYW5ub3RhdGlvbl9jc3YnLCAKICAgICAgICAgICAgICAgICAgICBwYXN0ZTAodGlzc3VlX29mX2ludGVyZXN0LCAiX2Ryb3BsZXRfYW5ub3RhdGlvbi5jc3YiKSkKd3JpdGUuY3N2KHRpc3NAbWV0YS5kYXRhWyxjKCdjaGFubmVsJywnYW5ub3RhdGlvbicsJ2NlbGxfb250b2xvZ3lfaWQnKV0sIGZpbGU9ZmlsZW5hbWUpCmBgYAoK